/*
    vm:vm实例对象
    exp:表达式
    cb:回调函数(持有更新器 及 更新器对应的节点)
*/
function Watcher(vm, exp, cb) {
    // this:Watcher实例对象
    this.cb = cb;
    this.vm = vm;
    this.exp = exp;
    // watcher会把与其相关的所有的dep的id存在depIds中
    this.depIds = {};
    //构建dep和watcher的多对多关系!!!
    this.value = this.get();
}

Watcher.prototype = {
    update: function() {
        this.run();
    },
    run: function() {
        //exp 在 vm中对应最新的值!!!
        var value = this.get();
        var oldVal = this.value;
        if (value !== oldVal) {
            this.value = value;
            //真正的更新!!!!!!!
            this.cb.call(this.vm, value, oldVal);
        }
    },
    addDep: function(dep) {
        //this:watcher
        if (!this.depIds.hasOwnProperty(dep.id)) {
            //a的dep.subs:[插值对应的watcher,v-html对应的watcher,v-text对应的watcher]
            //b的dep.subs:[插值对应的watcher,v-html对应的watcher,v-text对应的watcher]
            //c的dep.subs:[插值对应的watcher,v-html对应的watcher,v-text对应的watcher]
            //d的dep.subs:[插值对应的watcher,v-html对应的watcher]
            dep.addSub(this);

            //插值对应的watcher.depIds:{0:a的dep,1:b的dep,2:c的dep,3:d的dep}
            //v-html对应的watcher.depIds:{0:a的dep,1:b的dep,2:c的dep,3:d的dep}
            //v-text对应的watcher.depIds:{0:a的dep,1:b的dep,2:c的dep}
            this.depIds[dep.id] = dep;
        }
    },
    get: function() {
        Dep.target = this; //打开target ; this:wacther
        var value = this.getVMVal();
        Dep.target = null;//关闭target
        return value;
    },
    getVMVal: function() {
        var exp = this.exp.split('.');
        var val = this.vm._data;
        exp.forEach(function(k) {
            //exp: a.b.c.d
            val = val[k];
        });
        return val;
    }
};